package com.blog.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.common.result.R;
import com.blog.common.result.RPage;
import com.blog.entity.dto.ArticleDTO;
import com.blog.entity.dto.ArticleQueryDTO;
import com.blog.entity.dto.ArticleTagDTO;
import com.blog.entity.dto.TagsDTO;
import com.blog.entity.po.*;
import com.blog.entity.vo.ArticleVO;
import com.blog.mapper.*;
import com.blog.service.IArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 文章表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-03-24
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private CategoryMapper categoryMapper;


    @Autowired
    private ArticleTagMapper articleTagMapper;

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public RPage<ArticleVO> articleList(ArticleQueryDTO dto) {

        RPage<ArticleVO> voPage = new RPage<>();
        List<ArticleVO> vos = new ArrayList<>();
        if (dto.getCurrentPage() == null) {
            List<Article> articleList = lambdaQuery().orderByDesc(Article::getUpdateTime).in(Article::getArticleStatus,1,0).list();
            List<ArticleVO> articleVOS = BeanUtil.copyToList(articleList, ArticleVO.class);
            voPage.setData(articleVOS);
            voPage.setTotal((long) articleVOS.size());
            return voPage;
        }
        // 分页查询
        Page<Article> page = Page.of(dto.getCurrentPage(), dto.getPageSize());
        lambdaQuery()
                .orderByDesc(Article::getUpdateTime)
                .like(!Objects.equals(dto.getTitle(), "") && dto.getTitle() != null, Article::getTitle, dto.getTitle())
                .page(page);
        List<Article> articleList = page.getRecords();
        if (!articleList.isEmpty()) {
            // 如果接收的参数中 articleStatus 不为空需要对数据进行过滤
            if (dto.getArticleStatus() != null) {
                articleList = articleList.stream().filter(article -> Objects.equals(article.getArticleStatus(), dto.getArticleStatus())).collect(Collectors.toList());
            }
            vos = BeanUtil.copyToList(articleList, ArticleVO.class);
            if (!vos.isEmpty()) {
                // 查询分类信息
                List<String> catIds = articleList.stream().map(Article::getCatId).collect(Collectors.toList());
                LambdaQueryWrapper<Category> lqwCat = new LambdaQueryWrapper<>();
                lqwCat.in(Category::getId, catIds);
                List<Category> categoryList = categoryMapper.selectList(lqwCat);

                // 查询标签信息
                List<String> articleIds = articleList.stream().map(Article::getId).collect(Collectors.toList());
                List<TagsDTO> tagsList = articleMapper.getTagsList(articleIds);


                // 封装数据
                for (ArticleVO vo : vos) {
                    for (Category category : categoryList) {
                        if (category.getId().equals(vo.getCatId())) {
                            vo.setCatName(category.getCatName());
                        }
                    }
                    for (TagsDTO tagsDTO : tagsList) {
                        if (Objects.equals(vo.getId(), tagsDTO.getId())) {
                            List<Tag> tags = getTags(tagsDTO);
                            vo.setTags(tags);
                        }
                    }
                }
            }
        }

        voPage.setTotal(page.getTotal());
        voPage.setData(vos);
        return voPage;
    }

    private static List<Tag> getTags(TagsDTO tagsDTO) {
        List<String> nameList = Arrays.asList(tagsDTO.getTagNames().split(","));
        List<String> colorList = Arrays.asList(tagsDTO.getColors().split(","));
        List<Tag> tags = new ArrayList<>();
        for (int i = 0; i < nameList.size(); i++) {
            Tag tag = new Tag();
            tag.setTagName(nameList.get(i));
            tag.setColor(colorList.get(i));
            tags.add(tag);
        }
        return tags;
    }

    @Override
    public ArticleVO getArticleById(Long id) {
        // 查询基础信息
        Article article = getById(id);
        // 查询分类信息
        Category category = categoryMapper.selectById(article.getCatId());
        // 查询标签信息
        List<Tag> tags = articleMapper.getTagsById(id);
        List<String> tagNames = tags.stream().map(Tag::getTagName).collect(Collectors.toList());
        // 用户信息
        User user = userMapper.selectById(article.getCreateBy());

        // 修改浏览量
        lambdaUpdate()
                .eq(Article::getId, id)
                .set(Article::getView, article.getView() + 1)
                .update();

        // 封装数据
        ArticleVO vo = BeanUtil.copyProperties(article, ArticleVO.class);
        vo.setCatName(category.getCatName());
        vo.setTags(tags);
        vo.setCreateName(user.getNickname());


        return vo;
    }

    @Override
    public void updateStatusById(Long id) {
        Article article = lambdaQuery()
                .eq(Article::getId, id)
                .one();
        if (Objects.isNull(article)) {
            throw new RuntimeException("文章不存在");
        }

        if (article.getArticleStatus().equals(2)) {
            throw new RuntimeException("该文章已经删除了");
        }

        lambdaUpdate()
                .eq(Article::getId, id)
                .set(Article::getArticleStatus, 2)
                .update();

    }

    @Override
    public void editArticle(ArticleDTO dto) {
        Article one = lambdaQuery()
                .eq(Article::getId, dto.getId())
                .one();
        if (Objects.isNull(one)) {
            throw new RuntimeException("文章不存在");
        }
        // 修改文章的基础信息
        Article article = BeanUtil.copyProperties(dto, Article.class);
        updateById(article);

        // 修改文章的标签 （ 删除原来的 ， 新增 ）都是操作中间表
        String[] tags = dto.getTags();
        // 根据文章id删除文章对应的标签
        LambdaQueryWrapper<ArticleTag> lqwDel = new LambdaQueryWrapper<>();
        lqwDel.in(ArticleTag::getArticleId, dto.getId());
        articleTagMapper.delete(lqwDel);

        // 新增
        saveTag(dto.getId(), tags);

    }

    // TODO 新增标签
    private void saveTag(String articleId, String[] tags) {
        ArrayList<ArticleTag> arrayList = new ArrayList<>();
        for (String tagId : tags) {
            Random random = new Random();
            int meId = random.nextInt(32); // 机械id
            int daId = random.nextInt(32); // 数据中心id
            if (meId == daId) {
                daId = daId + 1;
            }
            ArticleTag articleTag = new ArticleTag();
            // 生成 ID ， 生成雪花类型的id
            Snowflake snowflake = new Snowflake(meId, daId);
            long id = snowflake.nextId();

            articleTag.setId(id + "");
            articleTag.setArticleId(articleId);
            articleTag.setTagId(tagId);
            arrayList.add(articleTag);
        }
        articleTagMapper.batchSave(arrayList);
    }


    @Override
    public void saveArticle(ArticleDTO dto) {
        // 新增文章基础信息
        Article article = BeanUtil.copyProperties(dto, Article.class);
        boolean b = save(article);
        if (!b) {
            throw new RuntimeException("新增文章失败");
        }

        // 新增文章标签
        saveTag(article.getId(), dto.getTags());


    }
}
